package ro.brite.android.nehe02;

import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import ro.brite.android.opengl.R;
import ro.brite.android.opengl.common.Utils;
import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
import android.opengl.GLUtils;

public class GlRenderer implements Renderer {

	//----------------------------------------------------------------------
	// 三角形、四边形的顶点坐标、顶点颜色值，用FloatBuffer来组织
	private static float[] triangleCoords = new float[] {
		 0,  1,  0,
		 1, -1,  1,
		 1, -1, -1,
		-1, -1, -1,
		-1, -1,  1,
		 1, -1,  1
	};
	private static float[] triangleColors = new float[] {
		1, 0, 0, 1,
		0, 1, 0, 1,
		0, 0, 1, 1,
		0, 1, 0, 1,
		0, 0, 1, 1,
		0, 1, 0, 1
	};
	private static float[] quadVertexCoords = new float[] {
		-1, 1, 0,
		-1,-1, 0,
		 1, 1, 0,
		 1,-1, 0
	};
	private static float[] quadTexCoords = new float[] {
		0, 1,
		0, 0,
		1, 1,
		1, 0,
	};
	
	private static FloatBuffer triangleVertexBuffer;
	private static FloatBuffer triangleColorBuf;
	
	private static FloatBuffer quadVertexCoordBuffer;
	private static FloatBuffer quadTexCoordBuffer;
	
	private static ScenseState state;
	
	static {
		triangleVertexBuffer = FloatBuffer.wrap(triangleCoords);
		triangleColorBuf = FloatBuffer.wrap(triangleColors);
		quadVertexCoordBuffer = FloatBuffer.wrap(quadVertexCoords);
		quadTexCoordBuffer = FloatBuffer.wrap(quadTexCoords);
		state = new ScenseState();
	}
	//----------------------------------------------------------------------

	private Context context;
	private IntBuffer texturesBuffer;
	
	public GlRenderer(Context context){
		this.context = context;
	}
	
	public void onSurfaceCreated(GL10 gl, EGLConfig config) {
		gl.glShadeModel(GL10.GL_SMOOTH);
		gl.glClearColor(0, 0, 0, 0);

		gl.glClearDepthf(1.0f);
		gl.glEnable(GL10.GL_DEPTH_TEST);
		gl.glDepthFunc(GL10.GL_LEQUAL);

		gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);

		// create texture
		gl.glEnable(GL10.GL_TEXTURE_2D);
		texturesBuffer = IntBuffer.allocate(1);
		gl.glGenTextures(1, texturesBuffer);
		gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(0));
		
		// setup texture parameters
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_LINEAR);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_CLAMP_TO_EDGE);
		gl.glTexParameterx(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_CLAMP_TO_EDGE);
		
		// set the texture
		Bitmap texture = Utils.getTextureFromBitmapResource(context, R.drawable.nehe_texture_glass);
		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, texture, 0);
		texture.recycle();
	}

	public void onDrawFrame(GL10 gl) {
		gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);

		gl.glMatrixMode(GL10.GL_MODELVIEW);
		gl.glLoadIdentity();

		// draw triangle
//		gl.glTranslatef(-1.5f, 0, -6);
//		gl.glTranslatef(0, 0, -6);
		gl.glTranslatef(0, 1.2f, 0);
		gl.glRotatef(state.triAngle, 0, 1, 0);
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, triangleVertexBuffer);
		gl.glColorPointer(4, GL10.GL_FLOAT, 0, triangleColorBuf);
//		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 3);
		gl.glDrawArrays(GL10.GL_TRIANGLE_FAN, 0, 6);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_COLOR_ARRAY);

		// draw quad
		gl.glLoadIdentity();	// 重要，否则四边形的动画会受三角形动画的影响
		gl.glTranslatef(0, -1.2f, 0);
		gl.glRotatef(state.quadAngle, 1, 0, 0);
		
//		gl.glColor4f(0.5f, 0.5f, 1.0f, 1.0f);
//		gl.glBindTexture(GL10.GL_TEXTURE_2D, texturesBuffer.get(0));
		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, quadVertexCoordBuffer);
		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, quadTexCoordBuffer);
		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
		
		state.triAngle += 0.8f;
		state.quadAngle -= 0.5f;
	}

	public void onSurfaceChanged(GL10 gl, int width, int height) {
		// avoid division by zero
		if (height == 0) height = 1;
		// draw on the entire screen
		gl.glViewport(0, 0, width, height);
		// setup projection matrix
		gl.glMatrixMode(GL10.GL_PROJECTION);
		gl.glLoadIdentity();
		GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 1.0f, 100.0f);
		
		GLU.gluLookAt(gl, 0, 0, 6, 0, 0, 0, 0, 1, 0);
	}

}
